package cqrtplm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hustcad.plm.pdm.file.model.dto.UploadFileDTO;
import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.controller.TyplmPartAlternateController;
import com.hustcad.plm.pdm.partbom.dto.InsertPartDTO;
import com.hustcad.plm.pdm.partbom.enums.PartBomErrorCodeEnum;
import com.hustcad.plm.pdm.partbom.query.PartUsageCountQuery;
import com.hustcad.plm.pdm.partbom.vo.PartAlterLinkVO;
import com.hustcad.plm.pdm.partbom.vo.PdmPartInfoVO;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.utils.ArgumentUtils;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.constant.IpAddressConstant;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.CustomerPowerRecordModel;
import cqrtplm.dto.query.CrmApiQueryDTO;
import cqrtplm.dto.query.CustomerQueryDTO;
import cqrtplm.entity.RtCfgStatusInfoDO;
import cqrtplm.mapper.CrmApiMapper;
import cqrtplm.mapper.RtCfgStatusInfoMapper;
import cqrtplm.service.CrmApiService;
import cqrtplm.vo.CrmApiResponseVO;
import cqrtplm.vo.ModuleVO;
import cqrtplm.vo.RtCfgStatusInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Supplier;

/**
 * @description:
 * @author: zhengxiong.jiang
 * @createDate: 2025-07-21
 * @version: 1.0
 */
@Slf4j
@Service
public class CrmApiServiceImpl implements CrmApiService {

    @Resource
    private CrmApiMapper crmApiMapper;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private TyplmPartAlternateController typlmPartAlternateController;
    @Resource
    private RtCfgStatusInfoMapper rtCfgStatusInfoMapper;
    //机型内部名称
    @Value("${STATUS_INFO_PARTTYPE}")
    private String STATUS_INFO_PARTTYPE;
    //开发令
    @Value("${STATUS_INFO_DEVCODE}")
    private String STATUS_INFO_DEVCODE;
    @Override
    public CrmApiResponseVO getClientCodeList(CrmApiQueryDTO queryDTO) {

        String body = HttpRequest.get(
                        IpAddressConstant.CRM_CS_KHBMIP + "?ClientCode=" + queryDTO.getClientCode() + "&SapClientCode=" + queryDTO.getSapclientcode())
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(queryDTO))
                .execute().body();
        CrmApiResponseVO<CrmApiResponseVO.CodeDataVO> crmApiResponseVO = JSONUtil.toBean(body, CrmApiResponseVO.class);
        return crmApiResponseVO;
    }

    @Override
    public CrmApiResponseVO getCRMOrderList(CrmApiQueryDTO queryDTO) {
        String body = HttpRequest.post(IpAddressConstant.CRM_CS_DDIP)
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(queryDTO))
                .execute().body();
        //        CrmApiResponseVO<CrmApiResponseVO.DdDataVO> crmApiResponseVO = JSONUtil.toBean(body, CrmApiResponseVO.class);
        // 2. 使用 Hutool 解析为 Java 对象（含 Hutool 的 JSONNull 处理）
        CrmApiResponseVO<CrmApiResponseVO.DdDataVO> crmApiResponseVO = JSONUtil.toBean(body,
                                                                                       new TypeReference<CrmApiResponseVO<CrmApiResponseVO.DdDataVO>>() {},
                                                                                       false); // 关闭严格模式，允许 JSONNull

        // 3. 清理响应中的 JSONNull，转为标准 Java null
        //        this.cleanJsonNulls(crmApiResponseVO);
        return crmApiResponseVO;
    }

    @Override
    public CrmApiResponseVO getClientModelList(CrmApiQueryDTO queryDTO) {
        String body = HttpRequest.get(
                        IpAddressConstant.CRM_CS_KHJXIP + "?ClientCode=" + queryDTO.getClientCode() + "&ClientModel=" + queryDTO.getClientModel())
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(queryDTO))
                .setConnectionTimeout(50000)  // 设置连接超时
                .setReadTimeout(50000)        // 设置读取超时
                .execute().body();
        CrmApiResponseVO<CrmApiResponseVO.ClientModelCode> crmApiResponseVO = JSONUtil.toBean(body,
                                                                                              new TypeReference<CrmApiResponseVO<CrmApiResponseVO.ClientModelCode>>() {},
                                                                                              false); // 关闭严格模式，允许 JSONNull
        return crmApiResponseVO;
    }

    @Override
    public CrmApiResponseVO getSysItemDetailList() {
        String body = HttpRequest.get(
                IpAddressConstant.CRM_CS_YJLX)
                .header("Content-Type", "application/json")
                .setConnectionTimeout(50000)  // 设置连接超时
                .setReadTimeout(50000)        // 设置读取超时
                .execute().body();
        CrmApiResponseVO crmApiResponseVO = JSONUtil.toBean(body,
                                                            new TypeReference<CrmApiResponseVO>() {},
                                                            false); // 关闭严格模式，允许 JSONNull
        return crmApiResponseVO;
    }

    @Override
    public List<CustomerPowerRecordModel> getCustomerPowerRecordModels(CustomerQueryDTO queryDTO) {
        // 创建参数Map
        Map<String, Object> params = new HashMap<>();
        params.put("certid", queryDTO.getCertid());
        params.put("devcode", queryDTO.getDevcode());
        params.put("customcode", queryDTO.getCustomcode());
        params.put("debugger", queryDTO.getDebugger());

        // 执行存储过程调用
        crmApiMapper.getCustomerPowerRecordModels(params);

        // 从params中获取游标结果
        @SuppressWarnings("unchecked")
        List<CustomerPowerRecordModel> result = (List<CustomerPowerRecordModel>) params.get("cursor");

        System.out.println("Result size: " + (result != null ? result.size() : 0));
        return result != null ? result : Collections.emptyList();
    }

    @Override
    public void buildXqzt() {
        List<RtCfgStatusInfoDO> list = crmApiMapper.selectStatusInfo();
        list.stream().forEach(i -> {
            this.savePdmPartInfo(i);
        });
    }


    private PdmPartInfoVO savePdmPartInfo(RtCfgStatusInfoDO rtCfgStatusInfoDO) {
        String jsonXqzt183 = "{\"folderName\":\"需求状态表\",\"folderId\":\"748981769688678400\",\"folderPath\":\"/需求状态表/需求状态表\",\"containerID\":\"748981727594643456\",\"containerType\":\"ty.inteplm.product.CTyPDMLinkProduct\",\"containerName\":\"需求状态表\",\"productPath\":\"需求状态表\",\"typeOid\":\"725884644494311424\",\"typeName\":\"状态需求表\",\"productID\":\"748981727594643456\",\"typeOType\":\"ty.inteplm.part.CTyPart|StatusRequirementsTable\",\"partView\":\"Design\",\"lifecycleTemplate\":\"润通通用生命周期模板\",\"partNumber\":\"part202510251454300665755\",\"lifecycleTemplateID\":\"751073324083789824\",\"lifecycleTemplateName\":\"润通通用生命周期模板\",\"number\":\"part202510251454300665755\",\"name\":\"2222\",\"collapsible\":\"0\",\"productType\":\"2222\",\"devCode\":\"X46\",\"ibaAttribute\":{\"productType\":[\"2222\"],\"devCode\":[\"X46\"]}}";
        PdmPartInfoVO partInfoVO = new PdmPartInfoVO();
        InsertPartDTO insertPartDTO = JSONUtil.toBean(jsonXqzt183, InsertPartDTO.class);
        if (Objects.nonNull(insertPartDTO)) {
            LinkedHashMap<String, List<String>> ibaAttribute = new LinkedHashMap<>();
            ibaAttribute.put("productType", Arrays.asList(rtCfgStatusInfoDO.getProducttype()));
            ibaAttribute.put("devCode", Arrays.asList(rtCfgStatusInfoDO.getDevcode()));
            insertPartDTO.setIbaAttribute(ibaAttribute);
            insertPartDTO.setName(
                    rtCfgStatusInfoDO.getStatustitle() == null ? "无" : rtCfgStatusInfoDO.getStatustitle());
            insertPartDTO.setDescription(
                    rtCfgStatusInfoDO.getStatedescription() == null ? "无" : rtCfgStatusInfoDO.getStatustitle());
            insertPartDTO.setPartNumber(rtCfgStatusInfoDO.getStatuscode());
            ArgumentUtils.checkArgumentNull(insertPartDTO.getPartView(),
                                            PartBomErrorCodeEnum.EXCEPTION_PARAM_VIEW_ID_IS_EMPTY.getLocaleMessage());
        }
        try {
           partInfoVO = typlmPdmPartService.insertPart(new UploadFileDTO(), new LinkedHashMap<>(),
                                                                      insertPartDTO);
        }catch (Exception e){

        }
        if(ObjectUtil.isNotEmpty(partInfoVO)){
            crmApiMapper.updateOid(partInfoVO.getOid(),partInfoVO.getOtype(),rtCfgStatusInfoDO.getStatusid());
        }
        return partInfoVO;
    }


    @Override
    public void createDemandStatusTemplate() {
        List<ModuleVO> moduleVOS = crmApiMapper.selectModule();
        if (moduleVOS == null) {
            return;
        }
        int sequenceNumber = 030001;
        for (ModuleVO moduleVO : moduleVOS) {
            try {
                sequenceNumber++;
                this.creat(moduleVO, sequenceNumber);
            } catch (Exception e) {
                throw new RuntimeException("创建模块失败: " + moduleVO, e);
            }
        }
//        this.relationship();
    }


    //创建模块
    @Transactional(rollbackFor = Exception.class)
    public void creat(ModuleVO rtCfgStatusInfoDO, int sequenceNumber) {
        String insertPartDto = "{\"folderName\":\"需求状态模板\",\"folderId\":\"747238704946495488\",\"folderPath\":\"/9-需求模板库/需求状态模板\",\"containerID\":\"715669729733902336\",\"containerType\":\"ty.inteplm.product.CTyPDMLinkProduct\",\"containerName\":\"9-需求模板库\",\"productPath\":\"9-需求模板库\",\"typeOid\":\"745134160075309056\",\"typeName\":\"需求状态模板\",\"classId\":\"\",\"classDisplayName\":\"\",\"productID\":\"715669729733902336\",\"typeOType\":\"ty.inteplm.part.CTyPart|状态需求模板\",\"partView\":\"Design\",\"lifecycleTemplate\":\"润通通用生命周期模板\",\"partNumber\":\"XQMB011\",\"lifecycleTemplateID\":\"751073324083789824\",\"lifecycleTemplateName\":\"润通通用生命周期模板\",\"refType\":\"\",\"number\":\"XQMB011\",\"name\":\"1025002\",\"collapsible\":\"0\",\"productManName\":\"机型负责人\",\"ibaAttribute\":{\"refType\":[\"\"],\"productManName\":[\"机型负责人\"]}}";
        String statusMsg = "XQMB2511" + sequenceNumber;
        InsertPartDTO insertPartDTO = JSONUtil.toBean(insertPartDto, InsertPartDTO.class);
        if (Objects.nonNull(insertPartDTO)) {
            LinkedHashMap<String, List<String>> ibaAttribute = new LinkedHashMap<>();
            ibaAttribute.put("productManName", Arrays.asList(rtCfgStatusInfoDO.getPRODUCTMANNAME()));
            insertPartDTO.setPartNumber(statusMsg);
            insertPartDTO.setName(rtCfgStatusInfoDO.getModulename());
            ArgumentUtils.checkArgumentNull(insertPartDTO.getPartView(),
                                            PartBomErrorCodeEnum.EXCEPTION_PARAM_VIEW_ID_IS_EMPTY.getLocaleMessage());
        }
        PdmPartInfoVO partInfoVO = typlmPdmPartService.insertPart(new UploadFileDTO(), new LinkedHashMap<>(),
                                                                  insertPartDTO);

        // 添加空值检查
        if (partInfoVO == null || partInfoVO.getMasteredoid() == null) {
            throw new RuntimeException("创建模板失败，无法获取 masteredoid，moduleid: " + rtCfgStatusInfoDO.getModuleid());
        }

        String masteredoid = String.valueOf(partInfoVO.getMasteredoid());
        String moduleid = rtCfgStatusInfoDO.getModuleid();
        log.info("保存的模块masteredoid为: {}，原本的moduleid为:{}", masteredoid, moduleid);

        // 统一更新并检查结果
        updateAndCheck(() -> crmApiMapper.updateModule(moduleid, masteredoid), "DSPF_STATUS_MODULE", moduleid);
        updateAndCheck(() -> crmApiMapper.updateModuleitem(moduleid, masteredoid), "RT_CFG_STATUSMODULEITEM", moduleid);
        updateAndCheck(() -> crmApiMapper.updateModuleitemsub(moduleid, masteredoid), "RT_CFG_STATUSMODULEITEMSUB", moduleid);
        updateAndCheck(() -> crmApiMapper.updateinfo(moduleid, masteredoid), "RT_CFG_STATUS_INFO", moduleid);
        updateAndCheck(() -> crmApiMapper.updateinfodetail(moduleid, masteredoid), "RT_CFG_STATUS_INFODETAIL", moduleid);
    }

    // 统一更新检查方法
    private void updateAndCheck(Supplier<Integer> updateFunction, String tableName, String moduleid) {
        int updatedRows = updateFunction.get();
        log.info("更新{}表结果: {}，moduleid: {}", tableName, updatedRows, moduleid);
        if (updatedRows == 0) {
            log.warn("未找到匹配的{}记录，moduleid: {}", tableName, moduleid);
        }
    }

    //产品型谱与模板创建关系
    @Transactional(rollbackFor = Exception.class)
    public void relationship() {
        //查询所有产品型谱的编码
        List<String> strings = crmApiMapper.selectPartNumberAllProductSpectrum();
        String devCode = null;
        int i = 0;
        List<String> Partnumber = new ArrayList<>();
        for (String string : strings) {
            i++;
            //获取产品型谱的oid和编码
            PartDO partDO = typlmPdmPartService.queryLastPartDoByPartNumber(string);
            if (partDO == null) {
                Partnumber.add(string);
                continue;
            }
            BigInteger oid = partDO.getOid();
            String partNumber = partDO.getPartnumber();
            Map<String, List<AttributeVO>> attrValueByOidAndKeys = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                    Collections.singletonList(partDO.getOid()),
                    TableTypeConstrant.TY_PART_OTYPE,
                    Collections.singletonList(RTPlmConstant.DevelopmentOrder));
            if (attrValueByOidAndKeys != null){
                devCode = attrValueByOidAndKeys.get(String.valueOf(partDO.getOid())).get(0).getAttributeValue();
            }
            //获取模板的masterodid
            List<String> modulePartnumber = crmApiMapper.selectModuleIdBydevCode(devCode);
            if ( modulePartnumber.size() == 0){
                log.info("未找到对应的模板，devCode: {}", devCode);
                Partnumber.add(string);
                continue;
            }

            modulePartnumber.stream().forEach(ModulePartnumber -> {
                if (ModulePartnumber != null && ModulePartnumber.matches("\\d+")) {
                    String s = crmApiMapper.selectPartNumberBymasteredoid(ModulePartnumber);
                    PartDO modulePartDO = typlmPdmPartService.queryLastPartDoByPartNumber(s);
                    BigInteger oid1 = modulePartDO.getOid();
                    //                String partnumber = modulePartDO.getPartnumber();
                    List<PartAlterLinkVO> partAlterLinkVOList = new ArrayList<>();
                    PartAlterLinkVO partAlterLinkVO = new PartAlterLinkVO();
                    partAlterLinkVO.setAlternateForNumber(s);
                    partAlterLinkVO.setAlternateForOid(oid1);
                    partAlterLinkVO.setAlternateNumber(partNumber);
                    partAlterLinkVO.setAlternateOid(oid);
                    partAlterLinkVO.setReplacementType("a");

                    PartAlterLinkVO partAlterLinkVO2 = new PartAlterLinkVO();
                    partAlterLinkVO2.setAlternateForNumber(partNumber);
                    partAlterLinkVO2.setAlternateForOid(oid);
                    partAlterLinkVO2.setAlternateNumber(s);
                    partAlterLinkVO2.setAlternateOid(oid1);
                    partAlterLinkVO2.setReplacementType("a");
                    partAlterLinkVOList.add(partAlterLinkVO);
                    partAlterLinkVOList.add(partAlterLinkVO2);
                    typlmPartAlternateController.batchSavePartAlterLink(partAlterLinkVOList);
                }

            });

        }

    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void relationshipProductTypeManName() {
        //查询module主表的数据  拿到开发令和模板的关系  刷入机型负责人
        List<ModuleVO> moduleVOS = crmApiMapper.selectproductManName();
        for (ModuleVO moduleVO : moduleVOS){
            String devCode = moduleVO.getDevCode();
            String productType= moduleVO.getProductType();
            if (StrUtil.isBlank(devCode) || StrUtil.isBlank(productType) ){
                continue;
            }
            String objectNumber = rtCfgStatusInfoMapper.selectMoudleByProductType(STATUS_INFO_PARTTYPE,
                                                                                  productType,
                                                                                  STATUS_INFO_DEVCODE,
                                                                                  devCode);
            // 通过传入的参数获取零部件编码
            PartDO partDO = typlmPdmPartService.queryLastPartDoByPartNumber(objectNumber);
            if (partDO == null) {
//                return;
                continue;
            }

            List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();


            // 创建IBA DTO对象
            IbaDTO ibaDTO = new IbaDTO();
            ibaDTO.setKey("productManName");
            ibaDTO.setValue(moduleVO.getPRODUCTMANNAME());

            // 创建保存对象IBA DTO
            SaveObjIBADTO dto = new SaveObjIBADTO();
            dto.setObjIbaList(Collections.singletonList(ibaDTO));
            dto.setCTyEntityBaseDO(new CTyEntityBaseDO(partDO.getOid(), TableTypeConstrant.TY_PART_OTYPE));
            objWithIbaList.add(dto);

            // 批量保存IBA属性
            if (!objWithIbaList.isEmpty()) {
                typlmAttributeValueService.batchSaveIBAByObjList(objWithIbaList, false);
            }

        }
    }

    /**
     * 递归清理 JSONNull，替换为 null
     */
    private void cleanJsonNulls(Object obj) {
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            for (String key : jsonObj.keySet()) {
                Object value = jsonObj.get(key);
                if (value instanceof JSONNull) {
                    jsonObj.set(key, null); // JSONNull -> null
                } else {
                    cleanJsonNulls(value); // 递归处理子对象
                }
            }
        } else if (obj instanceof JSONArray) {
            JSONArray jsonArr = (JSONArray) obj;
            for (int i = 0; i < jsonArr.size(); i++) {
                Object item = jsonArr.get(i);
                if (item instanceof JSONNull) {
                    jsonArr.set(i, null); // JSONNull -> null
                } else {
                    cleanJsonNulls(item); // 递归处理数组元素
                }
            }
        }
    }

}
